﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Globalization;


namespace Boomerang.Common.Tracing
{
    public class FileTraceListener : TextWriterTraceListener
    {

        static CircularStream mStream;
        bool MaxQuotaInitialized = false;
        const string FileQuotaAttribute = "maxFileSizeKB";
        const string IncludeDateTimeAttribute = "includeDateTime";
        const long DefaultMaxQuota = 1000;
        const string DefaultTraceFile = "BoomerangTraces.txt";


        #region Member Functions

        private long MaxQuotaSize
        {
            //Get the MaxQuotaSize from configuration file
            //Set to Default Value if there are any problems

            get
            {
                long MaxFileQuota = 0;
                if (!this.MaxQuotaInitialized)
                {
                    try
                    {
                        string MaxQuotaOption = this.Attributes[FileTraceListener.FileQuotaAttribute];
                        if (MaxQuotaOption == null)
                        {
                            MaxFileQuota = DefaultMaxQuota;
                        }
                        else
                        {
                            MaxFileQuota = int.Parse(MaxQuotaOption, CultureInfo.InvariantCulture);
                        }
                    }
                    catch (Exception)
                    {
                        MaxFileQuota = DefaultMaxQuota;
                    }
                    finally
                    {
                        this.MaxQuotaInitialized = true;
                    }
                }

                if (MaxFileQuota <= 0)
                {
                    MaxFileQuota = DefaultMaxQuota;
                }

                //MaxFileQuota is in KB in the configuration file, convert to bytes

                MaxFileQuota = MaxFileQuota * 1024;
                return MaxFileQuota;
            }
        }

        private void DetermineOverQuota()
        {

            //Set the MaxQuota on the stream if it hasn't been done

            if (!this.MaxQuotaInitialized)
            {
                mStream.MaxQuotaSize = this.MaxQuotaSize;
            }

            //If we're past the Quota, flush, then switch files

            if (mStream.IsOverQuota)
            {
                base.Flush();
                mStream.SwitchFiles();
            }
        }

        #endregion

        #region FileWriterTraceListener Functions

        public FileTraceListener(string file)
            : base(mStream = new CircularStream(file))
        {
        }

        public FileTraceListener()
            : base(mStream = new CircularStream(DefaultTraceFile))
        {
        }

        protected override string[] GetSupportedAttributes()
        {
            return new string[] { FileTraceListener.FileQuotaAttribute };
        }       

        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
        {
            DetermineOverQuota();
            base.TraceData(eventCache, source, eventType, id, data);
        }

        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id)
        {
            DetermineOverQuota();
            base.TraceEvent(eventCache, source, eventType, id);
        }

        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
        {
            DetermineOverQuota();
            base.TraceData(eventCache, source, eventType, id, data);
        }

        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
        {
            DetermineOverQuota();
            base.TraceEvent(eventCache, source, eventType, id, format, args);
        }

        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
        {
            DetermineOverQuota();
            base.TraceEvent(eventCache, source, eventType, id, message);
        }

        public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId)
        {
            DetermineOverQuota();
            base.TraceTransfer(eventCache, source, id, message, relatedActivityId);

        }

        public override void WriteLine(string message)
        {
            base.Write(DateTime.Now.ToString());
            base.Write(" ");
            base.WriteLine(message);
        }

        #endregion

    }    
}
